from coin.exchange.kr_rest.feed.feed_impl import generate_feed_subscriber
from coin.exchange.kr_rest.feed.ws_feed_impl import generate_ws_feed_subscriber
from coin.exchange.kr_rest.order.order_impl import generate_order_subscriber
from coin.strategy.kr_hard_arb.config_util import read_json
from coin.exchange.shared.kr_rest.product import SharedProduct
from coin.exchange.base.kr_rest.product import NativeProduct


class ExchInfo(object):
  def __init__(self, exchange, product, feed, order):
    self.exchange = exchange
    self.product = product
    self.feed = feed
    self.order = order


class ArbInfo(object):
  def __init__(self, product, exch1, exch2, config_filename):
    self.product = product
    self.exch1 = exch1
    self.exch2 = exch2
    self.config = read_json(config_filename)


class ArbInfoGeneral(object):
  def __init__(self, currency, exchs, config_filename):
    assert type(currency) == str
    assert type(exchs) == list
    self.currency = currency
    self.exchs = exchs
    self.config = None
    if config_filename:
      self.config = read_json(config_filename)


def create_exchange_info(exchange, accounting_currency, key_file, currency, api_version_dict=None):
  market_type = "Spot"
  api_version_dict = api_version_dict or {}

  product = SharedProduct.FromStrPair(currency, accounting_currency)

  feed = generate_ws_feed_subscriber(market_type,
                                     exchange,
                                     api_version_dict.get('ws_feed_subscriber', None),
                                     product)

  order = generate_order_subscriber(market_type,
                                    exchange,
                                    api_version_dict.get('order_subscriber', None),
                                    product,
                                    key_file)
  return ExchInfo(exchange, product, feed, order)


def create_arb_info(currency,
                    exchange1,
                    exchange2,
                    key_file1,
                    key_file2,
                    api_version_dict1,
                    api_version_dict2,
                    config_filename):
  assert currency is not None and currency != "", currency
  assert exchange1 != exchange2, ("%s != %s" % (exchange1, exchange2))
  return ArbInfo(currency,
                 create_exchange_info(exchange1, 'KRW', key_file1, currency, api_version_dict1),
                 create_exchange_info(exchange2, 'KRW', key_file2, currency, api_version_dict2),
                 config_filename)


def create_arb_info_general(currency, exchanges, key_files, config_filename):
  assert currency is not None and currency != "", currency
  assert len(exchanges) == len(key_files), (exchanges, key_files)
  return ArbInfoGeneral(currency,
                        [
                            create_exchange_info(exchange, 'KRW', key_file, currency) for exchange,
                            key_file in zip(exchanges, key_files)
                        ],
                        config_filename)
